# @FileName  :  models.py
# @Time      :  2025/7/28 22:34
# @Author    :  Ayanami
# @info      :  ORM模型

from enum import Enum
from tortoise import fields, models
# from tortoise.fields import ReverseRelation


# 枚举类定义
class HonorType(str, Enum):
    CERTIFICATE = "certificate"
    MEDAL = "medal"


class CheckinStatus(str, Enum):
    NOT_CHECKED_IN = "未签到"
    CHECKED_IN = "已签到"
    LATE = "迟到"
    LEAVE = "请假"


class Gender(str, Enum):
    MALE = "男"
    FEMALE = "女"

class UserType(str, Enum):
    """用户类型枚举"""
    ADMIN = "admin"        # 机构端（管理员）
    TEACHER = "teacher"    # 教师端
    STUDENT = "student"    # 学员端

class DictionaryType(str, Enum):
    """字典类型枚举"""
    TEACHER_CATEGORY = "teacher_category"    # 教师分类
    STUDENT_SOURCE = "student_source"        # 学员来源
    COURSE_CATEGORY = "course_category"      # 课程分类
    NEWS_CATEGORY = "news_category"          # 资讯分类
    RESOURCE_CATEGORY = "resource_category"  # 资源分类


class Dictionary(models.Model):
    """字典表"""
    id = fields.IntField(pk=True)
    type = fields.CharEnumField(DictionaryType, description="字典类型")  # 使用枚举
    code = fields.CharField(max_length=50, description="字典编码")
    name = fields.CharField(max_length=100, description="字典名称")
    value = fields.CharField(max_length=200, null=True, description="字典值")
    sort_order = fields.IntField(default=0, description="排序")
    parent_id = fields.IntField(null=True, description="父级ID")
    is_active = fields.BooleanField(default=True, description="是否启用")
    description = fields.CharField(max_length=255, null=True, description="描述")

    created_at = fields.DatetimeField(auto_now_add=True)
    updated_at = fields.DatetimeField(auto_now=True)
    is_deleted = fields.BooleanField(default=False, description="是否已删除")

    class Meta:
        table = "dictionary"
        unique_together = (("type", "code"),)

# 模型定义
class Area(models.Model):
    """全国地域表"""
    id = fields.IntField(pk=True)
    name = fields.CharField(max_length=50, description="地域名称")
    code = fields.CharField(max_length=20, null=True, description="行政区划代码")

    class Meta:
        table = "area"


class User(models.Model):
    """统一用户认证表"""
    id = fields.IntField(pk=True)
    username = fields.CharField(max_length=50, unique=True, description="用户名")
    email = fields.CharField(max_length=100, unique=True, description="邮箱")
    password = fields.CharField(max_length=255, description="密码哈希值")
    phone = fields.CharField(max_length=20, unique=True, description="手机号")

    # 用户类型和状态
    user_type = fields.CharEnumField(UserType, description="用户类型")  # ADMIN, TEACHER, STUDENT
    is_active = fields.BooleanField(default=True, description="是否激活")
    is_verified = fields.BooleanField(default=False, description="是否已验证")

    # 关联字段
    teacher = fields.ForeignKeyField("models.Teacher", null=True, description="关联教师")
    student = fields.ForeignKeyField("models.Student", null=True, description="关联学员")
    agent = fields.ForeignKeyField("models.Agent", null=True, description="关联机构")

    # 登录相关
    last_login = fields.DatetimeField(null=True, description="最后登录时间")
    login_count = fields.IntField(default=0, description="登录次数")
    password_reset_token = fields.CharField(max_length=255, null=True, description="密码重置令牌")
    token_expires_at = fields.DatetimeField(null=True, description="令牌过期时间")

    created_at = fields.DatetimeField(auto_now_add=True)
    updated_at = fields.DatetimeField(auto_now=True)
    is_deleted = fields.BooleanField(default=False)

    class Meta:
        table = "user"


class Role(models.Model):
    """角色表"""
    id = fields.IntField(pk=True)
    name = fields.CharField(max_length=50, unique=True, description="角色名称")
    code = fields.CharField(max_length=30, unique=True, description="角色编码")
    description = fields.TextField(null=True, description="角色描述")
    is_system = fields.BooleanField(default=False, description="是否系统角色")

    created_at = fields.DatetimeField(auto_now_add=True)
    updated_at = fields.DatetimeField(auto_now=True)
    is_deleted = fields.BooleanField(default=False)

    class Meta:
        table = "role"


class Permission(models.Model):
    """权限表"""
    id = fields.IntField(pk=True)
    name = fields.CharField(max_length=100, description="权限名称")
    code = fields.CharField(max_length=50, unique=True, description="权限编码")
    module = fields.CharField(max_length=50, description="所属模块")
    action = fields.CharField(max_length=30, description="操作类型")  # create, read, update, delete
    resource = fields.CharField(max_length=50, description="资源类型")

    created_at = fields.DatetimeField(auto_now_add=True)
    updated_at = fields.DatetimeField(auto_now=True)
    is_deleted = fields.BooleanField(default=False)

    class Meta:
        table = "permission"

class UserRole(models.Model):
    """用户角色关联表"""
    id = fields.IntField(pk=True)
    user = fields.ForeignKeyField("models.User", description="用户")
    role = fields.ForeignKeyField("models.Role", description="角色")

    assigned_by = fields.IntField(description="分配者ID")
    assigned_at = fields.DatetimeField(auto_now_add=True, description="分配时间")
    expires_at = fields.DatetimeField(null=True, description="过期时间")

    created_at = fields.DatetimeField(auto_now_add=True)
    is_deleted = fields.BooleanField(default=False)

    class Meta:
        table = "user_role"
        unique_together = [("user", "role")]

class RolePermission(models.Model):
    """角色权限关联表"""
    id = fields.IntField(pk=True)
    role = fields.ForeignKeyField("models.Role", description="角色")
    permission = fields.ForeignKeyField("models.Permission", description="权限")

    created_at = fields.DatetimeField(auto_now_add=True)
    is_deleted = fields.BooleanField(default=False)

    class Meta:
        table = "role_permission"
        unique_together = [("role", "permission")]

class LoginLog(models.Model):
    """登录日志表"""
    id = fields.IntField(pk=True)
    user = fields.ForeignKeyField("models.User", description="用户", null=True)
    login_time = fields.DatetimeField(auto_now_add=True, description="登录时间")
    login_ip = fields.CharField(max_length=45, description="登录IP")
    user_agent = fields.TextField(description="用户代理")
    login_type = fields.CharField(max_length=20, description="登录方式")  # password, sms, email
    is_success = fields.BooleanField(description="是否成功")
    failure_reason = fields.CharField(max_length=100, null=True, description="失败原因")

    created_at = fields.DatetimeField(auto_now_add=True)

    class Meta:
        table = "login_log"



class Teacher(models.Model):
    """讲师表"""
    id = fields.IntField(pk=True)
    teacher_id = fields.CharField(max_length=20, unique=True, description="教工号")
    name = fields.CharField(max_length=50, description="讲师姓名")
    phone = fields.CharField(max_length=20, description="联系方式")
    id_card = fields.CharField(max_length=18, description="身份证号")
    specialty = fields.CharField(max_length=100, description="教学方向")
    hire_date = fields.DateField(description="入职时间")
    education = fields.TextField(description="教育经历")
    sessions_count = fields.IntField(default=0, description="授课场次")
    level = fields.CharField(max_length=50, description="职称级别")
    category: fields.ForeignKeyRelation[Dictionary] = fields.ForeignKeyField(
        "models.Dictionary", related_name="teacher_categories", description="分类"
    )
    notes = fields.TextField(null=True, description="备注")

    created_at = fields.DatetimeField(auto_now_add=True)
    updated_at = fields.DatetimeField(auto_now=True)
    is_deleted = fields.BooleanField(default=False, description="是否已删除")
    # deleted_at = fields.DatetimeField(null=True, description="删除时间")
    # 在Teacher类中新增
    email = fields.CharField(max_length=100, null=True, description="邮箱")
    is_active = fields.BooleanField(default=True, description="是否激活")

    class Meta:
        table = "teacher"


class Agent(models.Model):
    """培训机构表"""
    id = fields.IntField(pk=True)
    name = fields.CharField(max_length=100, description="机构名称")
    credit_code = fields.CharField(max_length=20, unique=True, description="统一社会信用代码")
    license_expire = fields.DateField(description="执照有效期")
    business_scope = fields.TextField(description="经营范围")
    legal_person = fields.CharField(max_length=50, description="法人")
    phone = fields.CharField(max_length=20, description="联系方式")
    trainee_count = fields.IntField(default=0, description="培训人数")
    training_sessions = fields.IntField(default=0, description="培训人次")
    service_direction = fields.CharField(max_length=100, description="服务方向")
    is_approved = fields.BooleanField(default=False, description="审核状态")

    area: fields.ForeignKeyRelation[Area] = fields.ForeignKeyField(
        "models.Area", related_name="agents", description="地区ID"
    )

    created_at = fields.DatetimeField(auto_now_add=True)
    updated_at = fields.DatetimeField(auto_now=True)
    is_deleted = fields.BooleanField(default=False, description="是否已删除")
    # deleted_at = fields.DatetimeField(null=True, description="删除时间")
    # 在Agent类中新增
    email = fields.CharField(max_length=100, null=True, description="邮箱")
    is_active = fields.BooleanField(default=True, description="是否激活")
    contact_person = fields.CharField(max_length=50, null=True, description="联系人")

    class Meta:
        table = "agent"


class Student(models.Model):
    """学员表"""
    id = fields.IntField(pk=True)
    student_id = fields.CharField(max_length=20, unique=True, description="学号")
    name = fields.CharField(max_length=50, description="姓名")
    gender = fields.CharEnumField(Gender, description="性别")
    phone = fields.CharField(max_length=20, description="手机号")
    birthday = fields.DateField(null=True, description="出生日期")
    id_card = fields.CharField(max_length=18, unique=True, description="身份证号")
    is_verified = fields.BooleanField(default=False, description="实名认证状态")
    wechat = fields.CharField(max_length=50, null=True, description="微信号")
    emergency_contact = fields.CharField(max_length=50, description="紧急联系人")
    emergency_phone = fields.CharField(max_length=20, description="紧急联系人电话")
    source: fields.ForeignKeyRelation[Dictionary] = fields.ForeignKeyField(
        "models.Dictionary", related_name="student_sources", description="来源"
    )

    work_experience = fields.TextField(null=True, description="工作经历")
    total_study_hours = fields.IntField(default=0, description="累计学习时长(小时)")
    honors_count = fields.IntField(default=0, description="获得荣誉数")
    notes = fields.TextField(null=True, description="备注")

    area: fields.ForeignKeyRelation[Area] = fields.ForeignKeyField(
        "models.Area", related_name="students", description="地区ID"
    )

    created_at = fields.DatetimeField(auto_now_add=True)
    updated_at = fields.DatetimeField(auto_now=True)
    is_deleted = fields.BooleanField(default=False, description="是否已删除")
    # deleted_at = fields.DatetimeField(null=True, description="删除时间")
    # 在Student类中新增
    email = fields.CharField(max_length=100, null=True, description="邮箱")
    is_active = fields.BooleanField(default=True, description="是否激活")

    class Meta:
        table = "student"


class Course(models.Model):
    """课程表"""
    id = fields.IntField(pk=True)
    title = fields.CharField(max_length=100, description="课程名称")
    parent_course = fields.IntField(null=True, description="父课程ID")
    category: fields.ForeignKeyRelation[Dictionary] = fields.ForeignKeyField(
        "models.Dictionary", related_name="course_categories", description="课程类型"
    )
    is_online = fields.BooleanField(default=True, description="是否在线课程")
    cover_image = fields.CharField(max_length=255, null=True, description="封面图片URL")
    video_resource = fields.CharField(max_length=255, null=True, description="视频云资源ID")
    live_url = fields.CharField(max_length=255, null=True, description="直播地址")
    schedule = fields.DatetimeField(null=True, description="直播/上课时间")
    is_premium = fields.BooleanField(default=False, description="是否精品课")
    enable_checkin = fields.BooleanField(default=False, description="是否启用签到")
    enrollment_count = fields.IntField(default=0, description="报名人数")
    notes = fields.TextField(null=True, description="备注")

    tags = fields.JSONField(default=list, description="课程标签")

    agent: fields.ForeignKeyRelation[Agent] = fields.ForeignKeyField(
        "models.Agent", related_name="courses", description="培训机构"
    )
    teacher: fields.ForeignKeyRelation[Teacher] = fields.ForeignKeyField(
        "models.Teacher", related_name="courses", description="讲师"
    )

    created_at = fields.DatetimeField(auto_now_add=True)
    updated_at = fields.DatetimeField(auto_now=True)
    is_deleted = fields.BooleanField(default=False, description="是否已删除")
    # deleted_at = fields.DatetimeField(null=True, description="删除时间")

    class Meta:
        table = "course"


class SignUp(models.Model):
    """报名表"""
    id = fields.IntField(pk=True)
    start_date = fields.DatetimeField(description="报名开始时间")
    end_date = fields.DatetimeField(description="报名结束时间")
    max_capacity = fields.IntField(description="最大报名人数")

    course: fields.ForeignKeyRelation[Course] = fields.ForeignKeyField(
        "models.Course", related_name="signups", description="课程"
    )

    created_at = fields.DatetimeField(auto_now_add=True)
    updated_at = fields.DatetimeField(auto_now=True)
    is_deleted = fields.BooleanField(default=False, description="是否已删除")
    # deleted_at = fields.DatetimeField(null=True, description="删除时间")

    class Meta:
        table = "signup"


class EnrollmentRecord(models.Model):
    """报名记录表"""
    id = fields.IntField(pk=True)
    signup_time = fields.DatetimeField(auto_now_add=True, description="报名时间")

    signup: fields.ForeignKeyRelation[SignUp] = fields.ForeignKeyField(
        "models.SignUp", related_name="enrollments", description="报名表"
    )
    student: fields.ForeignKeyRelation[Student] = fields.ForeignKeyField(
        "models.Student", related_name="enrollments", description="学员"
    )
    is_deleted = fields.BooleanField(default=False, description="是否已删除")
    # deleted_at = fields.DatetimeField(null=True, description="删除时间")

    class Meta:
        table = "enrollment_record"
        unique_together = (("signup", "student"),)


class CourseRecord(models.Model):
    """课程记录表"""
    id = fields.IntField(pk=True)
    checkin_time = fields.DatetimeField(null=True, description="签到时间")
    status = fields.CharEnumField(
        CheckinStatus,
        default=CheckinStatus.NOT_CHECKED_IN,
        description="签到状态"
    )
    study_duration = fields.IntField(default=0, description="本次学习时长(分钟)")

    course: fields.ForeignKeyRelation[Course] = fields.ForeignKeyField(
        "models.Course", related_name="records", description="课程"
    )
    student: fields.ForeignKeyRelation[Student] = fields.ForeignKeyField(
        "models.Student", related_name="course_records", description="学员"
    )

    created_at = fields.DatetimeField(auto_now_add=True)
    updated_at = fields.DatetimeField(auto_now=True)
    is_deleted = fields.BooleanField(default=False, description="是否已删除")
    # deleted_at = fields.DatetimeField(null=True, description="删除时间")

    class Meta:
        table = "course_record"


class Honor(models.Model):
    """荣誉表（勋章和证书共用）"""
    id = fields.IntField(pk=True)
    name = fields.CharField(max_length=100, description="荣誉名称")
    type = fields.CharEnumField(HonorType, description="类型")
    image_url = fields.CharField(max_length=255, null=True ,description="图片URL")
    issue_date = fields.DateField(description="颁发日期")

    course: fields.ForeignKeyRelation[Course] = fields.ForeignKeyField(
        "models.Course", related_name="honors", description="关联课程"
    )
    student: fields.ForeignKeyRelation[Student] = fields.ForeignKeyField(
        "models.Student", related_name="honors", description="学员"
    )

    created_at = fields.DatetimeField(auto_now_add=True)
    updated_at = fields.DatetimeField(auto_now=True)
    is_deleted = fields.BooleanField(default=False, description="是否已删除")
    # deleted_at = fields.DatetimeField(null=True, description="删除时间")

    class Meta:
        table = "honor"


class Achievement(models.Model):
    """学员风采表"""
    id = fields.IntField(pk=True)
    title = fields.CharField(max_length=100, description="成就标题")
    description = fields.TextField(description="成就描述")
    image_url = fields.CharField(max_length=255, null=True, description="图片URL")

    student: fields.ForeignKeyRelation[Student] = fields.ForeignKeyField(
        "models.Student", related_name="achievements", description="学员"
    )
    course: fields.ForeignKeyRelation[Course] = fields.ForeignKeyField(
        "models.Course", null=True, related_name="achievements", description="关联课程"
    )

    created_at = fields.DatetimeField(auto_now_add=True)
    updated_at = fields.DatetimeField(auto_now=True)
    is_deleted = fields.BooleanField(default=False, description="是否已删除")
    # deleted_at = fields.DatetimeField(null=True, description="删除时间")

    class Meta:
        table = "achievement"


class News(models.Model):
    """资讯表"""
    id = fields.IntField(pk=True)
    title = fields.CharField(max_length=200, description="标题")
    cover_image = fields.CharField(max_length=255, null=True, description="封面URL")
    abstract = fields.TextField(description="摘要")
    content = fields.TextField(description="富文本内容")
    is_top = fields.BooleanField(default=False, description="是否置顶")
    tags = fields.JSONField(default=list, description="标签列表")

    category: fields.ForeignKeyRelation[Dictionary] = fields.ForeignKeyField(
        "models.Dictionary", related_name="news_categories", description="分类"
    )

    created_at = fields.DatetimeField(auto_now_add=True)
    updated_at = fields.DatetimeField(auto_now=True)
    is_deleted = fields.BooleanField(default=False, description="是否已删除")
    # deleted_at = fields.DatetimeField(null=True, description="删除时间")

    class Meta:
        table = "news"


class Resource(models.Model):
    """资源表"""
    id = fields.IntField(pk=True)
    name = fields.CharField(max_length=200, description="资源名称")
    code = fields.CharField(max_length=50, unique=True, description="资源编码")
    cloud_id = fields.CharField(max_length=100, description="云存储ID")
    file_format = fields.CharField(max_length=20, description="文件格式")
    file_size = fields.CharField(max_length=20, description="文件大小")
    download_count = fields.IntField(default=0, description="下载次数")
    expiry_date = fields.DateField(null=True, description="到期时间")

    category: fields.ForeignKeyRelation[Dictionary] = fields.ForeignKeyField(
        "models.Dictionary", related_name="resource_categories", description="分类"
    )
    teacher: fields.ForeignKeyRelation[Teacher] = fields.ForeignKeyField(
        "models.Teacher", null=True, related_name="resources", description="上传人"
    )
    course: fields.ForeignKeyRelation[Course] = fields.ForeignKeyField(
        "models.Course", null=True, related_name="resources", description="关联课程"
    )

    created_at = fields.DatetimeField(auto_now_add=True)
    updated_at = fields.DatetimeField(auto_now=True)
    is_deleted = fields.BooleanField(default=False, description="是否已删除")
    # deleted_at = fields.DatetimeField(null=True, description="删除时间")

    class Meta:
        table = "resource"


